'use strict'
class Compile {
  constructor () {}
  escape (str) {
    return str.toString()
      .replace(/@/g, '@A')
      .replace(/\//g, '@S')
  }
  unescape (str) {
    return str.replace(/@A/g, '@')
      .replace(/@S/g, '/')
  }
  serialize (obj) {
    if (!obj) {
      return
    }
    var kvPairs = []
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        kvPairs.push(this.escape(key)
          .concat('@=')
          .concat(this.escape(obj[key])))
      }
    }
    return kvPairs.join('/')
      .concat('/')
  }
  deserialize (objStr) {
    if (!objStr) {
      return
    }
    var obj = {}
    var kvPairs = objStr.split('/')
    kvPairs.forEach(function (kvStr) {
      var kv = kvStr.split('@=')
      if (kv.length !== 2) {
        return
      }
      var key = this.unescape(kv[0])
      var value = this.unescape(kv[1])
      if (value.indexOf('@=') >= 0) {
        value = this.deserialize(value)
      }
      obj[key] = value
    }.bind(this))
    return obj
  }
}

module.exports = new Compile()
